package me.caofeng.interceptor;

import me.caofeng.annotation.Authentication;
import me.caofeng.enums.ResponseCode;
import me.caofeng.enums.Role;
import me.caofeng.pojo.Response;
import me.caofeng.pojo.User;
import org.springframework.web.method.HandlerMethod;
import org.springframework.web.servlet.HandlerInterceptor;
import org.springframework.web.servlet.ModelAndView;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

/**
 * Copyright © 2017曹峰. All rights reserved.
 *
 * @Prject: mall
 * @Package: me.caofeng.interceptor
 * @Description: 认证过滤器,需要在web配置文件中和设置拦截器及拦截目标
 * @Author: 曹峰 blog.caofeng.me
 * @Date: 2017-06-16 21:22
 * @Version: V1.0
 */
public class AuthorInterceptor implements HandlerInterceptor {

    /**
     * @Author:曹峰 blog.caofeng.me
     * @Date: 2017/7/4 9:20
     * @Description: 在目标方法执行前执行，取出目标方法的可执行权限，与当前用户的权限进行匹配
    */
    public boolean preHandle(HttpServletRequest request,
                             HttpServletResponse response,
                             Object handler) throws Exception {

        Role role = extraRole((HandlerMethod) handler);

        if (null == role) {
            return true;
        }

        User user = (User) request.getSession().getAttribute("user");

        if (null == user || null == user.getRole()) {
            Response.response(ResponseCode.FORBIDDEN, response, "请先登陆", null);
            return false;
        }

        if (role != user.getRole()) {
            Response.response(ResponseCode.FORBIDDEN, response, "没有权限访问", null);
            return false;
        }
        return true;
    }

    public void postHandle(HttpServletRequest request, HttpServletResponse response, Object handler, ModelAndView modelAndView) throws Exception {

    }

    public void afterCompletion(HttpServletRequest request, HttpServletResponse response, Object handler, Exception ex) throws Exception {
    }

    /**
     * @Author:曹峰 blog.caofeng.me
     * @Date: 2017/6/17 13:04
     * @Description: 从被拦截对象中取出注解中定义的用户角色
     */
    private Role extraRole(HandlerMethod handlerMethod) {
        Role role = null;
        Authentication authentication = handlerMethod.getBean().getClass().getAnnotation(Authentication.class);
        if (null != authentication) {
            role = authentication.role();
        }

        authentication = handlerMethod.getMethodAnnotation(Authentication.class);

        if (null != authentication) {
            role = authentication.role();
        }

        return role;
    }

}
